﻿using System.Security.Cryptography;
using System.Text;
using System.IO;
using System;

public class Rijndael
{
    private const int RIJNDAEL_SECRET_KEY_SIZE_BITS = 256;
    private const int RIJNDAEL_INITIAL_VECTOR_SIZE_BITS = 128;

    public static ICryptoTransform CreateRijndaelEncryptor(string password)
    {
        byte[] salt = Encoding.ASCII.GetBytes(password.Length.ToString());
        PasswordDeriveBytes passwordDerivedBytes = new PasswordDeriveBytes(password, salt);
        byte[] secretKey = passwordDerivedBytes.GetBytes(RIJNDAEL_SECRET_KEY_SIZE_BITS / 8);
        byte[] initialVector = passwordDerivedBytes.GetBytes(RIJNDAEL_INITIAL_VECTOR_SIZE_BITS / 8);
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
        ICryptoTransform encryptor = RijndaelCipher.CreateEncryptor(secretKey, initialVector);
        return encryptor;
    }

    public static byte[] EncryptBytes(byte[] bytesToEncrypt, string password)
    {
        ICryptoTransform encryptor = CreateRijndaelEncryptor(password);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream =
            new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        using (cryptoStream)
        {
            cryptoStream.Write(bytesToEncrypt, 0, bytesToEncrypt.Length);
            cryptoStream.FlushFinalBlock();
            byte[] encryptedBytes = memoryStream.ToArray();
            return encryptedBytes;
        }
    }

    public static string EncryptString(string stringToEncrypt, string password)
    {
        byte[] bytesToEncrypt = Encoding.UTF8.GetBytes(stringToEncrypt);
        byte[] encryptedBytes = EncryptBytes(bytesToEncrypt, password);
        string encryptedString = Convert.ToBase64String(encryptedBytes);
        return encryptedString;
    }

    public static ICryptoTransform CreateRijndaelDecryptor(string password)
    {
        byte[] salt = Encoding.ASCII.GetBytes(password.Length.ToString());
        PasswordDeriveBytes passwordDerivedBytes = new PasswordDeriveBytes(password, salt);
        byte[] secretKey = passwordDerivedBytes.GetBytes(RIJNDAEL_SECRET_KEY_SIZE_BITS / 8);
        byte[] initialVector = passwordDerivedBytes.GetBytes(RIJNDAEL_INITIAL_VECTOR_SIZE_BITS / 8);
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
        ICryptoTransform decryptor = RijndaelCipher.CreateDecryptor(secretKey, initialVector);
        return decryptor;
    }

    public static byte[] DecryptBytes(byte[] encryptedBytes, string password)
    {
        ICryptoTransform encryptor = CreateRijndaelDecryptor(password);
        MemoryStream encryptedBytesStream = new MemoryStream(encryptedBytes);
        MemoryStream decryptedBytesStream = new MemoryStream();
        CryptoStream cryptoStream =
            new CryptoStream(encryptedBytesStream, encryptor, CryptoStreamMode.Read);
        using (cryptoStream)
        {
            byte[] buffer = new byte[encryptedBytes.Length];
            while (true)
            {
                int bytesRead = cryptoStream.Read(buffer, 0, buffer.Length);
                if (bytesRead == 0)
                {
                    break;
                }
                decryptedBytesStream.Write(buffer, 0, bytesRead);
            }
            byte[] decryptedBytes = decryptedBytesStream.ToArray();
            return decryptedBytes;
        }
    }

    public static string DecryptString(string encryptedString, string password)
    {
        byte[] encryptedBytes = Convert.FromBase64String(encryptedString);
        byte[] decryptedBytes = DecryptBytes(encryptedBytes, password);
        string decryptedString = Encoding.UTF8.GetString(decryptedBytes);
        return decryptedString;
    }
    
    //static void Main()
    //{
    //    string originalMessage = "aaa";
    //    Console.WriteLine("Original message: {0}", originalMessage);
    //    string password = "$3cR3t-P@$$w0rd";
    //    string encryptedMessage = EncryptString(originalMessage, password);
    //    Console.WriteLine("Encrypted message: {0}", encryptedMessage);
    //    string decryptedMessage = DecryptString(encryptedMessage, password);
    //    Console.WriteLine("Decrypted message: {0}", decryptedMessage);
    //}

}

